// miniprogram/pages/game.js
const Background = require("../../components/js/Background.js");
const WaterParticle = require("../../components/js/WaterParticle.js");
const Tadpole = require("../../components/js/Tadpole.js");
const Camera = require("../../components/js/Camera.js");
const Arrow = require("../../components/js/Arrow.js");
const WebSocketService = require("../../components/js/WebSocketService.js");
const Message = require("../../components/js/Message.js")

Page({
  /**
   * 页面的初始数据
   */
  data: {
    playerInfo: {
      name: "",
      maxMomentum: 3,
      size: 4,
      color: "#FFA500",
      lifeTime: 0
    },
    isMessage: false,
    messageContent: "",
    width: "100",
    height: "100",
    waterParticleArray: [],
    myTadpole: null,
    tadpoles: [],
    camera: null,
    canvas: null,
    ctx: null,
    mouse: {
      x: 0,
      y: 0,
      worldx: 0,
      worldy: 0,
      tadpole: null
    },
    keyNav: {
      x: 0,
      y: 0
    },
    arrows: [],
    messageQuota: 5,
    webSocket: null,
    webSocketService: null,
    test: 0
  },

  touchMoveListen: function(e) {
    // console.log(e.touches[0].x)
    this.data.mouse.x = e.touches[0].x;
    this.data.mouse.y = e.touches[0].y;
  },
  touchStartListen: function(e) {
    this.data.mouse.clicking = true;
    let model = this.data;
    if (model.myTadpole) {
      model.myTadpole.momentum = model.myTadpole.targetMomentum = model.myTadpole.maxMomentum;
    }

    let touch = e.touches[0];
    if (touch) {
      this.data.mouse.x = touch.x;
      this.data.mouse.y = touch.y;
    }
  },
  touchEndListen: function() {
    let model = this.data;
    if (model.myTadpole) {
      model.myTadpole.targetMomentum = 0;
    }
  },

  getMouseWorldPosition: function() {
    let mouse = this.data.mouse;
    let camera = this.data.camera;
    let canvas = this.data.canvas;
    return {
      x: (mouse.x + (camera.x * camera.zoom - canvas.width / 2)) / camera.zoom,
      y: (mouse.y + (camera.y * camera.zoom - canvas.height / 2)) / camera.zoom
    }
  },

  /**
   * 入口函数
   */
  run: function(ctx, width, height) {
    let wxThis = this;

    // 蝌蚪
    this.data.myTadpole = new Tadpole(wxThis.data.playerInfo.name, wxThis.data.playerInfo.maxMomentum,
      wxThis.data.playerInfo.size, wxThis.data.playerInfo.color);
    this.data.myTadpole.id = -1;
    this.data.tadpoles[this.data.myTadpole.id] = this.data.myTadpole;

    // 年龄
    let interval = setInterval(function() {
      wxThis.setData({
        "playerInfo.lifeTime": wxThis.data.playerInfo.lifeTime+1
      });
      if (wxThis.data.playerInfo.lifeTime > 15) {
        clearInterval(interval);
      }
    }, 6000)

    // 粒子
    for (let i = 0; i < 150; i++) {
      this.data.waterParticleArray.push(new WaterParticle());
    }

    // 镜头
    this.data.camera = new Camera(this.data.canvas, ctx, this.data.myTadpole.x, this.data.myTadpole.y);

    this.data.arrows = {};

    // 网络连接
    let domain_arr = ['fuyou.sunan.me'];
    // let domain_arr = ['127.0.0.1'];
    this.data.webSocket = wx.connectSocket({
      url: 'wss://' + domain_arr[Math.floor(Math.random() * domain_arr.length + 1) - 1] + ':8222'
    })
    this.data.webSocketService = new WebSocketService(this.data);

    wx.onSocketOpen(function(res) {
      wxThis.data.webSocketService.authorize("", "")
      wxThis.data.webSocketService.hasConnection = true;
    });

    wx.onSocketClose(function(res) {
      wxThis.data.webSocketService.connectionClosed();
    });

    wx.onSocketMessage(function(res) {
      try {
        let data = JSON.parse(res.data);
        wxThis.data.webSocketService.processMessage(data);
      } catch (res) {
        console.log(res)
      }
    })

  },

  sendMessage: function(msg) {
    if (this.data.messageQuota > 0) {
      this.data.messageQuota--;
      this.data.webSocketService.sendMessage(msg);
    }
  },

  gameUpdate: function() {
    let wxThis = this;
    // 
    if (this.data.messageQuota < 5 && this.data.myTadpole.age % 50 == 0) {
      this.data.messageQuota++;
    }

    // Update myTadpole
    let keyNav = wxThis.data.keyNav;
    let myTadpole = wxThis.data.myTadpole;
    let tadpoles = wxThis.data.tadpoles;
    let mouse = wxThis.data.mouse;

    if (keyNav.x != 0 || keyNav.y != 0) {
      myTadpole.userUpdate(tadpoles, myTadpole.x + keyNav.x, myTadpole.y + keyNav.y);
    } else {
      let mvp = wxThis.getMouseWorldPosition();
      mouse.worldx = mvp.x;
      mouse.worldy = mvp.y;
      myTadpole.userUpdate(tadpoles, mouse.worldx, mouse.worldy);
    }

    let webSocketService = this.data.webSocketService;
    if (myTadpole.age % 6 == 0 && myTadpole.changed > 1 && webSocketService.hasConnection) {
      myTadpole.changed = 0;
      webSocketService.sendUpdate(myTadpole);
    }

    wxThis.data.camera.update(this.data);

    // Update tadpoles
    for (let id in this.data.tadpoles) {
      this.data.tadpoles[id].update(mouse);
    };

    // Update waterParticles
    for (let i in this.data.waterParticleArray) {
      wxThis.data.waterParticleArray[i].update(wxThis.data.camera.getOuterBounds(), wxThis.data.camera.zoom)
    }

    // Update arrows
    for (let i in this.data.arrows) {
      let cameraBounds = this.data.camera.getBounds();
      let arrow = this.data.arrows[i];
      arrow.update();
    }
  },

  gameDraw: function() {
    let wxThis = this;
    let ctx = this.data.ctx;
    let canvas = this.data.canvas;

    this.data.camera.setupContext();

    // Draw waterParticles
    for (let i in this.data.waterParticleArray) {
      this.data.waterParticleArray[i].draw(ctx)
    }

    // Draw tadpoles
    for (let id in this.data.tadpoles) {
      this.data.tadpoles[id].draw(ctx);
    }

    // Start UI layer (reset transform matrix)
    this.data.camera.startUILayer();

    // Draw arrows
    for (let i in this.data.arrows) {
      this.data.arrows[i].draw(ctx, canvas);
    }

    //

  },

  /**
   * 游戏循环
   */
  gameLoop: function(ctx, width, height) {
    let wxThis = this;
    setInterval(function() {
      wxThis.gameUpdate();
      wxThis.gameDraw();
    }, 30)
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    let wxThis = this;
    console.log(options)
    this.data.playerInfo.name = options.name;
    this.data.playerInfo.color = options.color;
    this.data.playerInfo.size = options.size;
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {
    let wxThis = this;
    const canvasName = "gameCanvas"
    const query = wx.createSelectorQuery()
    query.select("#" + canvasName)
      .fields({
        node: true,
        size: true,
        context: true,
      })
      .exec((res) => {
        // console.log(res)
        const canvas = res[0].node
        wxThis.data.canvas = canvas;
        const ctx = canvas.getContext('2d')
        wxThis.data.ctx = ctx;
        const systemInfo = wx.getSystemInfoSync();
        const width = systemInfo.windowWidth;
        const height = systemInfo.windowHeight;
        // 设置画布全屏
        this.setData({
          width: width,
          height: height
        })
        // res[0].width = width
        // res[0].height = height
        canvas.width = width
        canvas.height = height

        this.run(ctx, width, height)
        this.gameLoop(ctx, width, height)
      })



  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function() {

  },
  openMessage: function() {
    let flag = true
    if (this.data.isMessage) {
      flag = false;
    } else {
      flag = true;
    }
    this.setData({
      isMessage: flag
    })
  },
  enterMessage: function(e) {
    this.setData({
      isMessage: false
    })
    let message = e.detail.value;
    if (this.data.playerInfo.lifeTime < 3 || (this.data.playerInfo.lifeTime > 9 && this.data.playerInfo.lifeTime < 12)) {
      this.sendMessage("嘤嘤嘤");
    } else {
      this.sendMessage(message);
    }
  }
})